home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 60750 / 60750.xpi / components / btMetricsLiteService.js < prev   
Text File  |  2010-01-20  |  12KB  |  374 lines

  1. const Cc = Components.classes;
  2. const Ci = Components.interfaces;
  3.  
  4. Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
  5. try {
  6.   Components.utils.import("resource://gre/modules/JSON.jsm");
  7.   JSON.stringify = JSON.toString;
  8. } catch (ex) {
  9.   /* Firefox 3.1 has native JSON support */
  10. }
  11.  
  12. const gPrefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
  13. const gPrefBranch = gPrefService.getBranch(null).QueryInterface(Ci.nsIPrefBranch2);
  14. const gObserver = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
  15. const gConsoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
  16. const gXULAppInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
  17. const gXULRuntime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
  18. const gExtensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
  19.  
  20. function BTMetricsLite() {
  21. }
  22.  
  23. BTMetricsLite.prototype = {
  24.     debug: false,
  25.     serverURI: '',
  26.     enabled: false,
  27.     bid: '',
  28.     browserVersion: 0,
  29.     extensionVersion: '',
  30.     os: '',
  31.     mDBConn: null,
  32.     timer: null,
  33.     sbServices: {
  34.         YAHOO_SB_SERVICE: 1,
  35.         ASK_SB_SERVICE: 2,
  36.         BING_SB_SERVICE: 3
  37.     },
  38.     request: null,
  39.  
  40.     observe: function(aSubject, aTopic, aData) {
  41.         switch(aTopic) {
  42.             case "app-startup":
  43.                 gObserver.addObserver(this,"profile-after-change",false);
  44.                 gObserver.addObserver(this,"profile-before-change",false);
  45.                 gObserver.addObserver(this,"xpcom-shutdown",false);
  46.                 gObserver.addObserver(this,"final-ui-startup",false);
  47.                 break;
  48.             case "xpcom-shutdown":
  49.                 gObserver.removeObserver(this,"profile-after-change");
  50.                 gObserver.removeObserver(this,"profile-before-change");
  51.                 gObserver.removeObserver(this,"final-ui-startup");
  52.                 gObserver.removeObserver(this,"xpcom-shutdown");
  53.                 break;
  54.             case "profile-before-change":
  55.                 this.packageData(false);
  56.                 break;
  57.             case "final-ui-startup":
  58.                 gObserver.addObserver(this, "brandthunder", false);
  59.                 this.init();
  60.                 break;
  61.             case "brandthunder":
  62.                 var currentBoom = "";
  63.                 try {
  64.                     currentBoom = this.getPref('extensions.brandthunder.currentBoom');
  65.                 } catch (ex) {}
  66.                 var brandObject = aSubject.wrappedJSObject;
  67.                 /* Need to accomodate old code */
  68.                 if (brandObject.booms) {
  69.                     /* If the currentBoom isn't in the brand Object we were given, */
  70.                     /* use the client short name */
  71.                     if (!brandObject.booms[currentBoom]) {
  72.                         currentBoom = brandObject.shortName;
  73.                     }
  74.                 }
  75.                 
  76.                 if (aData == "active") {
  77.                     this.extensionVersion = gExtensionManager.getItemForID(brandObject.extensionID).version;
  78.                     this.sendActiveStatus(currentBoom);
  79.                 } else {
  80.                     this.storeAction(currentBoom, aData);
  81.                 }
  82.                 return;
  83.         }
  84.     },
  85.     notify: function(timer) {
  86.         this.packageData(true);    
  87.     },
  88.     init: function() {
  89.         var env = Cc['@mozilla.org/process/environment;1'].getService(Ci.nsIEnvironment);
  90.         if (env.get('BRANDTHUNDER')) {
  91.             this.debug = true;
  92.         }
  93.  
  94.         this.enabled = this.getPref('extensions.btMetricsLite.enabled');
  95.         this.serverURI = this.getPref('extensions.btMetricsLite.uri');
  96.         var env = Cc['@mozilla.org/process/environment;1'].getService(Ci.nsIEnvironment);
  97.         if (this.debug) {
  98.             this.serverURI = 'https://btmetrics-dev.brandthunder.com/service';
  99.         }
  100.         if (!this.getPref('extensions.btMetricsLite.bid')) {
  101.             this.setPref('extensions.btMetricsLite.bid', this.generateBid());
  102.         }
  103.         this.bid = this.getPref('extensions.btMetricsLite.bid');
  104.         this.browserVersion = gXULAppInfo.version.match(/(\d+\.\d+)/)[1].replace('.', '');
  105.         this.os = gXULRuntime.OS;
  106.         
  107.         this.timer = Components.classes['@mozilla.org/timer;1'].createInstance(Components.interfaces.nsITimer);
  108.         if (this.debug) {
  109.             this.timer.initWithCallback(this, 30000, Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
  110.         } else {
  111.             this.timer.initWithCallback(this, 300000, Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
  112.         }
  113.  
  114.         var database = Components.classes['@mozilla.org/file/directory_service;1']
  115.                                      .getService(Components.interfaces.nsIProperties)
  116.                                      .get('ProfD', Components.interfaces.nsIFile);
  117.         database.append('btmetricslite.sqlite');
  118.         this.mDBConn = Components.classes['@mozilla.org/storage/service;1'].getService(Components.interfaces.mozIStorageService).openDatabase(database);
  119.             
  120.         this.sqlToObj("CREATE TABLE IF NOT EXISTS 'events' ('cid' VARCHAR(255) NOT NULL, 'action' VARCHAR(255) NOT NULL, 'created' DATETIME NOT NULL)");
  121.     },
  122.     getPref: function(name, defaultVal) {
  123.         try {
  124.             switch (gPrefBranch.getPrefType(name)) {
  125.                 case 32: //string
  126.                     return  gPrefBranch.getCharPref(name);
  127.                 case 64: //int
  128.                     return gPrefBranch.getIntPref(name);
  129.                 case 128: //bool
  130.                     return gPrefBranch.getBoolPref(name);
  131.             }
  132.         } catch (e) {
  133.         }
  134.         return defaultVal;
  135.     },
  136.  
  137.     setPref: function(name, val) {
  138.         if ((val === true) || (val === false)){
  139.             gPrefBranch.setBoolPref(name, val);
  140.         } else if (typeof val == 'string'){
  141.             gPrefBranch.setCharPref(name, val);
  142.         } else {
  143.             gPrefBranch.setIntPref(name, val);
  144.         }
  145.     },
  146.  
  147.     md5: function(str) {
  148.         var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Ci.nsIScriptableUnicodeConverter);
  149.         converter.charset = 'UTF-8';
  150.         var result = {};
  151.         var data = converter.convertToByteArray(str, result);
  152.         var ch = Cc['@mozilla.org/security/hash;1'].createInstance(Ci.nsICryptoHash);
  153.         ch.init(ch.MD5);
  154.         ch.update(data, data.length);
  155.         var hash = ch.finish(false);
  156.         
  157.         function toHexString(charCode) {
  158.             return ('0' + charCode.toString(16)).slice(-2);
  159.         }
  160.      
  161.         var s = [toHexString(hash.charCodeAt(i)) for (i in hash)].join('');
  162.      
  163.         return s;
  164.     },
  165.     timestamp: function(_131) {
  166.         var d = new Date();
  167.         var _133 = d.getTime();
  168.         var time = _133/1000;
  169.         var _135 = parseInt(time);
  170.         return (_131) ? time : _135;
  171.     },
  172.     generateBid: function() {
  173.         return this.md5(this.timestamp(true) + ':' + Math.random());
  174.     },
  175.         
  176.     storeAction: function(shortName, action) {
  177.         if (this.enabled) {
  178.             var localdate = new Date();
  179.             try {
  180.                 this.sqlToObj("INSERT INTO events " +
  181.                                              "(cid, action, created) " +
  182.                                              "VALUES " +
  183.                                              "('" + this.dbClean(shortName) + "', '" + this.dbClean(action) + "', '" + this.toTimeString(localdate) + "')");
  184.             } catch (e) {}
  185.         }
  186.     },
  187.                 
  188.     sendActiveStatus: function(currentBoom) {
  189.         var currentdate = new Date();
  190.         var currenttimestamp = currentdate.getTime() / 1000;
  191.         
  192.         var lastsent = this.getPref('extensions.btMetricsLite.lastsent');
  193.         if (lastsent) {
  194.             if ((currenttimestamp - lastsent) < 3600) {
  195.                 if (!this.debug) {
  196.                     return;
  197.                 }
  198.             }
  199.         }
  200.             
  201.         var searchSvc = Cc['@mozilla.org/browser/search-service;1']
  202.                                         .getService(Ci.nsIBrowserSearchService);
  203.         
  204.         if (searchSvc.currentEngine.description == "Yahoo! - BT") {
  205.             searchService = this.sbServices.YAHOO_SB_SERVICE;
  206.         } else if (searchSvc.currentEngine.description == "Ask - BT") {
  207.             searchService = this.sbServices.ASK_SB_SERVICE;
  208.         } else if (searchSvc.currentEngine.description == "Bing - BT") {
  209.             searchService = this.sbServices.BING_SB_SERVICE;
  210.         } else {
  211.             searchService = 0;
  212.         }
  213.         
  214.         this.sendData('active=1&cid=' + currentBoom + '&bid=' + this.bid + '&bv=' + this.browserVersion + '&os=' + this.os + '&ev=' + this.extensionVersion + '&sbs=' + searchService, false, true);
  215.         this.setPref('extensions.btMetricsLite.lastsent', currenttimestamp);
  216.     },
  217.  
  218.                 
  219.     toTimeString: function(localdate) {
  220.         return this.toDateString(localdate, 'y-m-d h:i:s', true);
  221.     },
  222.         
  223.     toDateString: function(localdate, format, showZeros) {
  224.         var gmt = localdate.getTime() + (localdate.getTimezoneOffset() * 60000);
  225.         var date = new Date(gmt);
  226.         
  227.         format = format.toLowerCase();
  228.         
  229.         // cast all values to strings
  230.         var day = '' + date.getDate(),
  231.             month = '' + (date.getMonth() + 1),
  232.             hour = '' + date.getHours(),
  233.             minute = '' + date.getMinutes(),
  234.             second = '' + date.getSeconds(),
  235.             year = '' + date.getFullYear();
  236.         
  237.         // pad leading zeros
  238.         if (showZeros) {
  239.             if (1 === day.length) {day = '0' + day;}
  240.             if (1 === month.length) {month = '0' + month;}
  241.             if (1 === hour.length) {hour = '0' + hour;}
  242.             if (1 === minute.length) {minute = '0' + minute;}
  243.             if (1 === second.length) {second = '0' + second;}
  244.         }
  245.         
  246.         return format.replace('y', year)
  247.                      .replace('d', day)
  248.                      .replace('h', hour)
  249.                      .replace('i', minute)
  250.                      .replace('s', second)
  251.                      .replace('m', month); // do month last as some months contain reserved letters
  252.     },
  253.     
  254.     clearTime: function(date) {
  255.         date.setHours(0);
  256.         date.setMinutes(0);
  257.         date.setSeconds(0);
  258.         date.setMilliseconds(0);
  259.         
  260.         return date;
  261.     },
  262.              
  263.                 
  264.     packageData: function(async) {
  265.         var dbObject = this.sqlToObj("SELECT * FROM events");
  266.         if (dbObject.length > 0) {
  267.             jsonString = JSON.stringify(dbObject);
  268.             var this_ptr = this;
  269.             this.sendData('bid=' + this.bid + '&ev=' + this.extensionVersion + '&events=' + jsonString, function(responseText) {
  270.                 this_ptr.sqlToObj("DELETE FROM events");
  271.             }, async);
  272.             
  273.             //temporary measure to make sure that the sqllite db is cleared on browser close
  274.             if (!async) {
  275.                 this.sqlToObj("DELETE FROM events");
  276.             }
  277.         }
  278.     },
  279.  
  280.     sendData: function(data, callback, async) {
  281.         this.request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
  282.         this.request.onreadystatechange = function() {
  283.             if (this.readyState == 4) {
  284.                 if (callback) {
  285.                     callback(this.responseText);
  286.                 }
  287.             }
  288.         };
  289.             
  290.         this.request.open('POST', this.serverURI, async);
  291.         this.request.setRequestHeader('Connection', 'close');
  292.         this.request.setRequestHeader('Keep-Alive', '');
  293.         this.request.setRequestHeader('Content-Length', data.length);
  294.         this.request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  295.         this.request.send(data);
  296.     },
  297.  
  298.     sqlToObj: function(sql, matches) {
  299.         var rs, error = false, eMessage;
  300.         if (matches == null) {
  301.             matches = [];
  302.         }
  303.  
  304.         var i, cols, ret, row = 0;
  305.         ret = [];
  306.         var statement = this.mDBConn.createStatement(sql);
  307.         var binds = false;
  308.         while (matches.length > 0) {
  309.             binds = true;
  310.             thisMatch = matches.pop();
  311.             if (thisMatch[0] == 'UTF8String') {
  312.                 statement.bindUTF8StringParameter(matches.length, thisMatch[2]);
  313.             } else if (thisMatch[0] == 'Int32') {
  314.                 statement.bindInt32Parameter(matches.length, thisMatch[2]);
  315.             } else if (thisMatch[0] == 'Blob') {
  316.                 statement.bindBlobParameter(matches.length, thisMatch[2]);
  317.             }
  318.         }
  319.         while (statement.executeStep()) {
  320.             cols = statement.columnCount;
  321.             ret[row] = new Object();
  322.             for (i = 0; i < cols; i++) {
  323.                 var mytype = statement.getTypeOfIndex(i);
  324.                 var myval;
  325.                 if (mytype == statement.VALUE_TYPE_NULL) {
  326.                     myval = statement.getIsNull(i);
  327.                 } else if (mytype == statement.VALUE_TYPE_INTEGER) {
  328.                     myval = statement.getInt32(i);
  329.                 } else if (mytype == statement.VALUE_TYPE_FLOAT) {
  330.                     myval = statement.getDouble(i);
  331.                 } else if (mytype == statement.VALUE_TYPE_TEXT) {
  332.                     myval = statement.getUTF8String(i);
  333.                 } else if (mytype == statement.VALUE_TYPE_BLOB) {
  334.                     myval = statement.getBlob(i);
  335.                 } else {
  336.                     myval = null;
  337.                 }
  338.                 ret[row][statement.getColumnName(i)] = myval;
  339.             }
  340.             row++;
  341.         }
  342.         statement.reset();
  343.         statement = null;
  344.  
  345.         return ret;
  346.     },
  347.  
  348.     dbClean: function(str) {
  349.         var pairs = [["'", "''"]];
  350.         for (var i = 0; i < pairs.length; i++) {
  351.             str = str.split(pairs[i][0]).join(pairs[i][1]);
  352.         }
  353.  
  354.         return str;
  355.     },
  356.  
  357.     log: function(string) {
  358.         gConsoleService.logStringMessage(string);
  359.     },
  360.  
  361.     classDescription: "Brand Thunder Metrics Lite",
  362.     contractID: "@brandthunder.com/btmetricslite;1",
  363.     classID: Components.ID("{5b578c72-d669-4ea9-8d9a-d049d6ade22c}"),
  364.     QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsITimerCallback]),
  365.     _xpcom_categories: [{
  366.         category: "app-startup",
  367.         service: true
  368.     }]
  369. }
  370.  
  371. function NSGetModule(compMgr, fileSpec) {
  372.     return XPCOMUtils.generateModule([BTMetricsLite]);
  373. }
  374.